﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DiscreteEventModel;
using DiscreteEventModel.Common;

namespace SpikingNeuralNetwork {

    using Model;

    public partial class Neuron {

        public class Input : DiscreteEvent<NeuralNetwork.NeuralState, NeuralNetwork> {

            public readonly double Potential;
            public readonly IEnumerable<Neuron> TargetNeurons;

            public Input(DiscreteEvent<NeuralNetwork.NeuralState, NeuralNetwork>.Runtime runtime, double timing, double potential, params Neuron[] targetNeurons)
                : base(runtime, timing) {
                this.Potential = potential;
                this.TargetNeurons = targetNeurons;
            }

            protected override DiscreteTime OnCommit(DiscreteEvent<NeuralNetwork.NeuralState, NeuralNetwork>.Runtime runtime, NeuralNetwork.NeuralState target) {
                Neuron targetNeuron = target as Neuron;
                if(targetNeuron.MembranePotential < targetNeuron.FiringThreshold) {
                    targetNeuron.MembranePotential += this.Potential;
                    if(targetNeuron.MembranePotential < targetNeuron.FiringThreshold) {
                        return DiscreteTime.Infinity;
                    }
                    targetNeuron.MembranePotential = targetNeuron.FiringThreshold;
                    return targetNeuron.Time;
                }
                return targetNeuron.CommitTime;
            }

            protected override IEnumerable<NeuralNetwork.NeuralState> GetTargets(DiscreteEvent<NeuralNetwork.NeuralState, NeuralNetwork>.Runtime runtime) {
                return this.TargetNeurons;
            }

            protected override void OnDispose(NeuralNetwork context) {
                throw new NotImplementedException();
            }
        }
    }
}
